// hdu5398
// 题意：每组case给定编号为 1...n(n≤10^5)个点，任意两点 i,j 的边权为gcd(i,j)。
//       现在你要求的是这 n 个点的最大生成树。 一共有最多 10^5 组case。
//
// 题解：最大生成树可以用lct来维护，case数很多肯定需要预处理。
//       我们从1...n逐个做，对于新加进来的点i，对于其所有因子，我们连一条边过去，
//       如果形成环就cut掉。可以想一下，新连进去的边一定是比原来的优的。
//       然后又是经典的处理边权点权的方法，因为lct不能直接保存边权，所以可以把边弄成点。
//
// 统计：2262ms, 50min, 1A
//
// run: time -p $exec < input
// flag: -g
// opt: 3
#include <cstdio>
#include <algorithm>

int const maxn = 200100;
int n = 100000;

struct edge
{
	int from, to, cost;
} edges[maxn];

struct node
{
	int parent, child[2];
	bool rev;
	int min_id;
	int value;
} memory[maxn];

void push_down(int u)
{
	if (!u) return;
	if (memory[u].rev) {
		std::swap(memory[u].child[0], memory[u].child[1]);
		memory[memory[u].child[0]].rev ^= true;
		memory[memory[u].child[1]].rev ^= true;
		memory[u].rev = false;
	}
}

void push_up(int u)
{
	push_down(u); push_down(memory[u].child[0]); push_down(memory[u].child[1]);
	memory[u].min_id = u;
	int l = memory[u].child[0], r = memory[u].child[1];
	if (memory[memory[l].min_id].value < memory[memory[u].min_id].value)
		memory[u].min_id = memory[l].min_id;
	if (memory[memory[r].min_id].value < memory[memory[u].min_id].value)
		memory[u].min_id = memory[r].min_id;
}

void rotate(int u, int is_left)
{
	int p = memory[u].parent;
	memory[p].child[!is_left] = memory[u].child[is_left];
	if (memory[u].child[is_left] != 0) memory[memory[u].child[is_left]].parent = p;
	memory[u].parent = memory[p].parent;
	if (memory[memory[p].parent].child[0] == p) memory[memory[u].parent].child[0] = u;
	else if (memory[memory[p].parent].child[1] == p) memory[memory[u].parent].child[1] = u;
	memory[u].child[is_left] = p;
	memory[p].parent = u;
	push_up(p);

}

void splay(int u)
{
	if (!u) return;
	push_down(u);
	for (int v, w; (v = memory[u].parent) != 0 && (memory[v].child[0] == u || memory[v].child[1] == u); ) {
		if ((w = memory[v].parent) != 0 && (memory[w].child[0] == v || memory[w].child[1] == v)) {
			push_down(w); push_down(v); push_down(u);
			bool is_left = v == memory[memory[v].parent].child[0];
			if (u == memory[v].child[is_left])
				rotate(u, !is_left), rotate(u, is_left);
			else
				rotate(v, is_left), rotate(u, is_left);
		} else {
			push_down(v); push_down(u);
			rotate(u, u == memory[v].child[0]);
			break;
		}
	}
	push_up(u);
}

int access(int u)
{
	int v = 0;
	for (; u; v = u, u = memory[u].parent) splay(u), memory[u].child[1] = v;
	return v;
}

void make_root(int u)
{
	memory[access(u)].rev ^= true;
	splay(u);
}

void link(int u, int v)
{
	make_root(u);
	memory[u].parent = v;
	access(u);
}

void cut(int u, int v)
{
	make_root(u);
	access(v);
	splay(v);
	memory[memory[v].child[0]].parent = 0;
	memory[v].child[0] = 0;
	push_up(v);
}

int query_min(int u, int v)
{
	make_root(u);
	access(v);
	splay(v);
	return memory[v].min_id;
}

int get_root(int u)
{
	for (u = access(u); memory[u].child[0]; u = memory[u].child[0]);
	return u;
}

int const inf = 1 << 30;
long long ans[maxn];
int tot = 1;

void lct_init()
{
	for (int i = 0; i <= 2 * n; i++) {
		memory[i].min_id = i;
		if (i <= n) memory[i].value = inf;
	}
}

void link_update(int i, int j)
{
	if (i == j) return;
	if (get_root(i) == get_root(j)) {
		int t = query_min(i, j);
		cut(t, edges[t - n].from);
		cut(t, edges[t - n].to);
		ans[i] -= edges[t - n].cost;
		ans[i] += j;
		edges[t - n].from = j;
		edges[t - n].to = i;
		edges[t - n].cost = j;
		memory[t].value = j;
		link(t, edges[t - n].from);
		link(t, edges[t - n].to);
	} else {
		edge tmp; tmp.from = i; tmp.to = j; tmp.cost = j;
		memory[tot + n].value = j;
		link(tot + n, i);
		link(tot + n, j);
		edges[tot++] = tmp;
		ans[i] += j;
	}
}

void init()
{
	lct_init();
	ans[1] = 0;
	for (int i = 2; i <= n; i++) {
		ans[i] = ans[i - 1];
		for (int j = 1; j * j <= i; j++) {
			if (i % j) continue;
			link_update(i, j);
			link_update(i, i/j);
		}
	}
}

int main()
{
	init();
	for (int tmp; std::scanf("%d", &tmp) != EOF; )
		std::printf("%lld\n", ans[tmp]);
}

